#include "blue_com.h"

#include <iostream>

using namespace std;

blue_com::blue_com()
{
}

bool blue_com::open(void)
{
	SOCKADDR_BTH sa;
	int sa_len = sizeof(sa);

	// initialize windows sockets
	WORD wVersionRequested;
	WSADATA wsaData;
	wVersionRequested = MAKEWORD( 2, 0 );
	if (WSAStartup(wVersionRequested, &wsaData) != 0 ) 
	{
		cout << "[BLUETOOTH] Couldn't initialize Windows sockets" << endl;
		return false;
	}

	// create the server socket
	server = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
	if (SOCKET_ERROR == server) 
	{
		cout << "[BLUETOOTH] Couldn't create server socket" << endl;
		return false;
	}

	// bind the server socket to an arbitrary RFCOMM port
	sa.addressFamily = AF_BTH;
	sa.btAddr = 0;
	sa.port = BT_PORT_ANY;
	if (SOCKET_ERROR == bind(server, (const sockaddr*)&sa, sizeof(SOCKADDR_BTH))) 
	{
		cout << "[BLUETOOTH] Couldn't bind to RFCOMM port" << endl;
	}

	listen(server, 1);

	// check which port we're listening on
	if (SOCKET_ERROR == getsockname(server, (SOCKADDR*)&sa, &sa_len)) 
	{
		cout << "[BLUETOOTH] Socket error occured" << endl;	
		return false;
	}
	cout << "[BLUETOOTH] Listening on RFCOMM port: " << sa.port << endl;

	// advertise the service
	CSADDR_INFO sockInfo;
	sockInfo.iProtocol = BTHPROTO_RFCOMM;
	sockInfo.iSocketType = SOCK_STREAM;
	sockInfo.LocalAddr.lpSockaddr = (LPSOCKADDR) &sa;
	sockInfo.LocalAddr.iSockaddrLength = sizeof(sa);
	sockInfo.RemoteAddr.lpSockaddr = (LPSOCKADDR) &sa;
	sockInfo.RemoteAddr.iSockaddrLength = sizeof(sa);

	WSAQUERYSET svcInfo = { 0 };
	svcInfo.dwSize = sizeof(svcInfo);
	svcInfo.dwNameSpace = NS_BTH;
	svcInfo.lpszServiceInstanceName = "LPMS Bluetooth base service";
	svcInfo.lpszComment = "LPMS Bluetooth base service";
	svcInfo.lpServiceClassId = (LPGUID) &SAMPLE_UUID;
	svcInfo.dwNumberOfCsAddrs = 1;
	svcInfo.lpcsaBuffer = &sockInfo;

	if (SOCKET_ERROR == WSASetService( &svcInfo, RNRSERVICE_REGISTER, 0)) 
	{
		cout << "[BLUETOOTH] Socket error occured" << endl;	
		return false;
	}

	SOCKADDR_BTH ca;
	int ca_len = sizeof(ca);
	char buf[1024] = { 0 };
	DWORD buf_len = sizeof(buf);

	client = accept (server, (LPSOCKADDR) &ca, &ca_len);

	if (SOCKET_ERROR == client) 
	{
		cout << "[BLUETOOTH] Socket error occured" << endl;	
		return false;
	}

	WSAAddressToString((LPSOCKADDR)&ca, (DWORD) ca_len, NULL, buf, &buf_len);
	cout << "[BLUETOOTH] Accepted connection from " << buf << endl;
	
	return true;
}
	
int blue_com::receive(char *buf)
{
	int received = 0;
	received = recv(client, buf, sizeof(buf), 0);

	if (received > 0) 
	{
		cout << "[BLUETOOTH] Received: " << buf << endl;
	}
	
	return received;
}

void blue_com::run(void)
{
	char buf[1024];
	int i;

	if (open() == true)
	{		
		while (stopped == false)
		{
			i = receive(buf);
			if (i > 0)
			{
				cout << buf << endl;
			}
		}
		close();
	} else {
		cout << "[BLUETOOTH] Failed to establish connection" << endl;
	}
}

void blue_com::close(void)
{
	closesocket(client);
	closesocket(server);
}

